﻿#ifndef __SINGLETON_H__
#define __SINGLETON_H__
#include "Common.h"

namespace sky
{

    // 懒汉模式
    template<class T, bool musetDelete = true>
    class Singleton
    {
        // 实例静态指针
        static T * _instance;

    public:
        static T& getInstance()
        {
            if (!_instance)
            {
                _instance = new T;
                if (musetDelete) atexit(releaseInstance);
            }

            return *_instance;
        }

    protected:
        /// 使用保护构造是为了用户不能在栈上声明一个实例
        Singleton(){}

        static void __cdecl releaseInstance()
        {
            if (_instance && musetDelete)
            {
                delete _instance;
                _instance = 0;
            }
        }
    };

	/// 静态实例指针初始化
	template <class T, bool mustDelete> T* Singleton<T, mustDelete>::_instance = NULL;



// ----------------------------------------------------------------------------------------------------

	/// 扩展的单实体模板，不关心对象的创建和销毁
	/// 采用外部new和delete，这种单实体的好处是外部能控制构造和析构的顺序
    template <typename T>
    class SingletonEx
    {
    
    protected:
        static T * _instance;

    public:
        SingletonEx()
        {
            _instance = static_cast<T*>(this);
        }

        ~SingletonEx()
        {
            assert(_instance);
            _instance = 0;
        }

        static T& getInstance()     {assert(_instance); return (*_instance);}
        static T* getInstancePtr()  {return _instance;}
    };

    template<typename T> T * SingletonEx<T>::_instance = 0;



    /** 单实例模板.
        示例：
        @code
        struct CFooSingleton : public SingletonEx<CFooSingleton>
        {
            Void foo()
            {
                Trace("foo!\n");
            }
        };	

        int main(int,int*)
        {
            new CFooSingleton();
            
            // 调用 foo 函数的方法：
            CFooSingleton::getInstance().foo();

            delete CFooSingleton::getInstancePtr();
        }
        @endcode
    */


    
} // namespace sky


#endif